<template>
  <div class="email-input">
    <a-input ref="emailInputEl" class="email-input-el" v-model:value="inputData" placeholder="请输入您的电子邮箱账户" @change="inputChange"/>
    <ul ref="quickUlEl" v-show="quickInputUlVisible">
      <li v-for="(item, index) in computedSuffixList" :key="item" :class="{ active: index === step }" @click="selectHandler(item)">
        {{ item }}
      </li>
    </ul>
  </div>
</template>

<script setup>
import {computed, onBeforeUnmount, onMounted, ref, watch, defineProps, defineEmits } from 'vue'

defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

const emailSuffixList = ['bohan.com.cn', 'df-emall.com', 'bohan-it.com', 'qq.com', '126.com', '163.com', 'gmail.com', 'sina.com', 'sohu.com', '139.com']
const inputData = ref('')
const emailInputEl = ref({})
const step = ref(0)
const quickUlEl = ref({})
const focus = ref(false)

// 输入的邮箱@后缀内容，过滤拼接出符合的输入项
const computedSuffixList = computed(() => {
  const [account, suffix = ''] = inputData.value.split('@')
  const filterSuffixList = suffix.trim().length === 0
      ? emailSuffixList : emailSuffixList.filter(item => item.indexOf(suffix.trim()) === 0)
  return filterSuffixList.map(item => account + '@' + item)
})
// 联想框，如果输入内容不为空，且过滤拼接后的列表不为空，且输入框内容不完全符合过滤列表的某一项， 则联想框显示
const quickInputUlVisible = computed(() => focus.value && inputData.value.trim().length > 0 && computedSuffixList.value.length > 0 && !computedSuffixList.value.find(item => item === inputData.value))

function inputChange() {
  emit('update:modelValue', inputData.value)
}

function selectHandler(text) {
  inputData.value = text
  inputChange()
}
// 列表 上一个 下一个计算
function quickListKeyComputedFn(stepNum) {
  step.value = step.value + stepNum
  step.value = step.value < 0 ? 0 : step.value
  step.value = step.value >= computedSuffixList.value.length  ? computedSuffixList.value.length - 1 : step.value
  if (quickUlEl.value) {
    quickUlEl.value.scrollBy(0, 28 * stepNum + (stepNum === 1 ? -10 : 10))
  }
}

function keyDownFn(e) {
  if (e.key === "ArrowUp") {
    quickListKeyComputedFn(-1)
  }
  if (e.key === "ArrowDown") {
    quickListKeyComputedFn(1)
  }
  if (e.key === 'Enter') {
    selectHandler(computedSuffixList.value[step.value])
  }
}

// 输入框 获取焦点时 分开是为了removeEvent
function emailInputFocus() {
    setTimeout(() => {
      focus.value = true
    }, 150)
}
// 输入框 失去焦点时 分开是为了removeEvent
function emailInputBlur() {
  setTimeout(() => {
    focus.value = false
  }, 150)
}

watch(computedSuffixList, (oldVal, newVal) => {
  if (oldVal.length !== newVal.length) {
    step.value = 0
  }
})

onMounted(() => {
  document.addEventListener("keydown", keyDownFn)
  if (emailInputEl.value) {
    emailInputEl.value.focus()
    focus.value = true
  }
  document.querySelector('.email-input-el').addEventListener('blur', emailInputBlur)
  document.querySelector('.email-input-el').addEventListener('focus', emailInputFocus)
})

onBeforeUnmount(() => {
  document.removeEventListener('keydown', keyDownFn)
  document.querySelector('.email-input-el').removeEventListener('blur', emailInputBlur)
  document.querySelector('.email-input-el').removeEventListener('focus', emailInputFocus)
})


</script>

<style lang="less" scoped>
.email-input{
  position: relative;
  &>ul{
    border-radius: 2px;
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    background: #fff;
    z-index: 99;
    border: 1px solid #ddd;
    max-height: 160px;
    overflow-y: auto;
    li{
      height: 28px;
      line-height: 26px;
      padding: 0 12px;
      z-index: 99;
      border-bottom: 1px solid #ddd;
      cursor: pointer;
      &:last-child{
        border-bottom: none;
      }
      &:hover, &.active{
        background: @hover-color;
      }
    }
  }
}
</style>